// Copyright (c) 2014 The Chromium Embedded Framework Authors. All rights
// reserved. Use of this source code is governed by a BSD-style license that
// can be found in the LICENSE file.

package org.cef.handler;

import org.cef.browser.CefBrowser;
import org.cef.misc.BoolRef;

/**
 * Implement this interface to handle events related to keyboard input. The
 * methods of this class will be called on the UI thread.
 */
public interface CefKeyboardHandler {

  /**
   * Structure representing keyboard event information.
   */
  public static final class CefKeyEvent {
    /**
     * Key event types.
     */
    public static enum EventType {
      /**
       * Notification that a key transitioned from "up" to "down"
       */
      KEYEVENT_RAWKEYDOWN,

      /**
       * Notification that a key was pressed. This does not necessarily
       * correspond to a character depending on the key and language. Use
       * KEYEVENT_CHAR for character input.
       */
      KEYEVENT_KEYDOWN,

      /**
       * Notification that a key was released
       */
      KEYEVENT_KEYUP,

      /**
       * Notification that a character was typed. Use this for text input. Key
       * down events may generate 0, 1, or more than one character event
       * depending on the key, locale, and operating system.
       */
      KEYEVENT_CHAR
    }

    CefKeyEvent(EventType typeAttr,
                int modifiersAttr,
                int windows_key_codeAttr,
                int native_key_codeAttr,
                boolean is_system_keyAttr,
                char characterAttr,
                char unmodified_characterAttr,
                boolean focus_on_editable_fieldAttr) {
      type = typeAttr;
      modifiers = modifiersAttr;
      windows_key_code = windows_key_codeAttr;
      native_key_code = native_key_codeAttr;
      is_system_key = is_system_keyAttr;
      character = characterAttr;
      unmodified_character = unmodified_characterAttr;
      focus_on_editable_field = focus_on_editable_fieldAttr;
    }

    /**
     * The type of keyboard event.
     */
    public final EventType type;

    /**
     * Bit flags describing any pressed modifier keys.
     * @see org.cef.handler.CefContextMenuHandler.EventFlags for values.
     */
    public final int modifiers;

    /**
     * The Windows key code for the key event. This value is used by the DOM
     * specification. Sometimes it comes directly from the event (i.e. on
     * Windows) and sometimes it's determined using a mapping function. See
     * WebCore/platform/chromium/KeyboardCodes.h for the list of values.
     */
    public final int windows_key_code;

    /**
     * The actual key code genenerated by the platform.
     */
    public final int native_key_code;

    /**
     * Indicates whether the event is considered a "system key" event (see
     * http://msdn.microsoft.com/en-us/library/ms646286(VS.85).aspx for details).
     * This value will always be false on non-Windows platforms.
     */
    public final boolean is_system_key;

    /**
     * The character generated by the keystroke.
     */
    public final char character;

    /**
     * Same as character but unmodified by any concurrently-held modifiers
     * (except shift). This is useful for working out shortcut keys.
     **/
    public final char unmodified_character;

    /**
     * True if the focus is currently on an editable field on the page. This is
     * useful for determining if standard key events should be intercepted.
     */
    public final boolean focus_on_editable_field;

    @Override
    public String toString() {
      return "CefKeyEvent [type=" + type + ", modifiers=" + modifiers
          + ", windows_key_code=" + windows_key_code + ", native_key_code="
          + native_key_code + ", is_system_key=" + is_system_key
          + ", character=" + character + ", unmodified_character="
          + unmodified_character + ", focus_on_editable_field="
          + focus_on_editable_field + "]";
    }
  }

  /**
   * Called before a keyboard event is sent to the renderer.
   * 
   * @param browser the corresponding browser.
   * @param event contains information about the keyboard event.
   * @param is_keyboard_shortcut set to true and return false, if
   *  the event will be handled in OnKeyEvent() as a keyboard shortcut.
   * @return true if the event was handled or false otherwise.
   */
  public boolean onPreKeyEvent(CefBrowser browser,
                               CefKeyEvent event,
                               BoolRef is_keyboard_shortcut);

  /**
   * Called after the renderer and JavaScript in the page has had a chance to
   * handle the event.
   * 
   * @param browser  the corresponding browser.
   * @param event contains information about the keyboard event.
   * @return true if the keyboard event was handled or false otherwise.
   */
  public boolean onKeyEvent(CefBrowser browser,
                            CefKeyEvent event);
}
